#ifndef __Y64_DISK_H__
#define __Y64_DISK_H__

/*
PIO模式
    组别            主控制器    从控制器        读取操作            写入操作
                    0x1f0       0x170                       数据
                    0x1f1       0x171           错误状态            写补偿（已废弃）
                    0x1f2       0x172                       操作扇区数
                    0x1f3       0x173                       扇区号/LBA(7:0)
                    0x1f4       0x174                   柱面号（7:0）/LBA(15:8)
                    0x1f5       0x175                   柱面号（15:8）/LBA(23:16)
    命令端口        0x1f6       0x176           设备配置寄存器，各位功能如下：
                                                    CHS模式         LBA模式
                                            bit7:   必须为1         必须为1
                                            bit6:   选择寻址模式，0为CHS模式，1为LBA模式
                                            bit5:   必须为1         必须为1
                                            bit4:   选择硬盘驱动器，0为主硬盘，1为从硬盘
                                            bit0~3: 磁头号          LBA（27:24）
                    0x1f7       0x177           控制器状态端口，同0x3f6/376     控制器命令端口，控制命令如下：
                                                                                    0xec    硬件设备识别信息
                                                                                    0x20    读扇区（28位LBA寻址模式）
                                                                                    0x24    扩展读扇区（48位LBA寻址模式）
                                                                                    0x30    写扇区（28位LBA寻址模式）
                                                                                    0x34    扩展写扇区（48位LBA寻址模式）
    -------------------------------------------------------------------------------------------------------------------------
                    0x3f6       0x376           状态寄存器，各位功能如下：      控制寄存器，各位功能如下：
                                                bit7=1: 控制器忙                bit2=1: 重启控制器
                                                bit6=1: 驱动器准备就绪              =0: 普通操作
     控制端口                                   bit3=1: 数据请求                bit1=1: 禁止中断请求
                                                bit0=1: 命令执行错误                =0: 使能中断请求（3f6使能IRQ14, 376使能IRQ15）
                                                注：其它位功能已经废弃

    系统上电或重启后，错误端口读出的状态信息描述了硬盘的诊断结果：
        位/值       驱动器0的状态描述           驱动器1的状态描述
        bit7        驱动器1出错                 保留
        0x05        控制器错误                  控制器错误
        0x04        ECC电路错误                 ECC电路错误
        0x03        扇区缓冲区错误              扇区缓冲区错误
        0x02        驱动器0出错                 驱动器1出错
        0x01        驱动器0和1无错误            驱动器1无错误
    当硬盘完成初始化并进入运行状态后，通过I/O端口0x1f1可取得命令执行的错误状态：
        bit7: 坏扇区
        bit6: 不可修复的数据错误
        bit4: 找不到ID或目标扇区
        bit2: 命令终止
        bit1: 已经达到介质末尾，仍未发现磁道0
        bit0: 无效长度、命令超时、介质错误等

硬盘设备识别信息结构：（512B）
    字序        功能描述
    0           常规配置字，bit15:为0表示ATA设备
    10~19       序列号（20个ASCII字符串）
    23~26       固件版本（8个ASCII字符串）
    27~46       型号（40个ASCII字符串）
    49          支持功能状态位，其中
                bit9: 为1表示支持LBA功能
                bit8: 为1表示支持DMA功能
    60~61       用户可寻址的全部逻辑扇区数（28位寻址命令）
    76          SATA功能，其中
                bit2: 为1表示支持SATA Gen2 3.0 GB/s传输速度
                bit1: 为1表示支持SATA Gen1 1.5 GB/s传输速度
    80          主版本号，其中
                bit8: 为1表示支持ATA/ATAPI-8
                bit7: 为1表示支持ATA/ATAPI-7
                bit6: 为1表示支持ATA/ATAPI-6
                bit5: 为1表示支持ATA/ATAPI-5
                bit4: 为1表示支持ATA/ATAPI-4
    81          次版本号
    100~103     用户可寻址的全部逻辑扇区数（48位寻址命令）
    176~205     当前介质序列号（60个ASCII字符串）
    222         传输类型主版本号，其中
                bit15~12: 表示传输类型，0为并行传输，1为串行传输，其他值保留
                位          并行传输        串行传输
                bit4:       保留            SATA Rev2.6
                bit3:       保留            SATA Rev2.5
                bit2:       保留            SATA II: Extensions
                bit1:       ATA/ATAPI-7     SATA 1.0a
                bit0:       ATA8-APT        ATA8-AST
    223         传输类型次版本号
    255         校验和
                bit15~8: 校验和补偿数值
                bit7~0: 0xA5
*/

#define PORT_DISK0_DATA                 0x1f0
#define PORT_DISK0_ERR_FEATURE          0x1f1
#define PORT_DISK0_SECTOR_CNT           0x1f2
#define PORT_DISK0_SECTOR_LOW           0x1f3
#define PORT_DISK0_SECTOR_MID           0x1f4
#define PORT_DISK0_SECTOR_HIGH          0x1f5
#define PORT_DISK0_DEVICE               0x1f6
#define PORT_DISK0_STATUS_CMD           0x1f7

#define PORT_DISK0_ALT_STA_CTL          0x3f6

#define PORT_DISK1_DATA                 0x170
#define PORT_DISK1_ERR_FEATURE          0x171
#define PORT_DISK1_SECTOR_CNT           0x172
#define PORT_DISK1_SECTOR_LOW           0x173
#define PORT_DISK1_SECTOR_MID           0x174
#define PORT_DISK1_SECTOR_HIGH          0x175
#define PORT_DISK1_DEVICE               0x176
#define PORT_DISK1_STATUS_CMD           0x177

#define PORT_DISK1_ALT_STA_CTL          0x376

#define DISK_STATUS_BUSY                (1 << 7)
#define DISK_STATUS_READY               (1 << 6)
#define DISK_STATUS_SEEK                (1 << 4)
#define DISK_STATUS_REQ                 (1 << 3)
#define DISK_STATUS_ERROR               (1 << 0)

typedef struct __attribute__((packed)){
    unsigned short general_cfg;         // 0 general config
    unsigned short obsolete0;           // 1 obsolete 过时，不再推荐使用
    unsigned short specific_cfg;        // 2 sepcific config
    unsigned short obsolete1;           // 3 obsolete
    unsigned short retired0[2];         // 4-5 retired 废弃，不再维护
    unsigned short obsolete2;           // 6 obsolete
    unsigned short compact_flash[2];    // 7-8 reserved for the compactflash association
    unsigned short retired1;            // 9 retired
    unsigned short serial_num[10];      // 10-19 serail number (20 ASCII characters)
    unsigned short retired2[2];         // 20-21 retired
    unsigned short obsolete3;           // 22 obsolete
    unsigned short firmware_ver[4];     // 23-26 firmware version (8 ASCII characters)
    unsigned short model_num[20];       // 27-46 model number (40 ASCII characters)
    unsigned short max_logical_transferred_per_drq; // 47   [15:8]=0x80, [7:0] 0x00: reserved
                                                    //                         0x01~0xff: maximumnuber of logical sectors that shall be transferred per DRQ data block on READ/WRITE MULTIPE commands
    unsigned short trusted_computing_feature_set_options;   // 48 trusted computing feature set options
    unsigned short capabilities0;       // 49 capabilities
    unsigned short capabilities1;       // 50 capabilities
    unsigned short obsolete4[2];        // 51-52 obsolete

    //	53	15:8	Free-fall Control Sensitivity
	//		7:3 	Reserved
	//		2 	the fields reported in word 88 are valid
	//		1 	the fields reported in words (70:64) are valid
	unsigned short report_88_70to64_valid;

	//	54-58	Obsolete
	unsigned short obsolete5[5];

	//	59	15:9	Reserved
	//		8	Multiple sector setting is valid	
	//		7:0	xxh current setting for number of logical sectors that shall be transferred per DRQ data block on READ/WRITE Multiple commands
	unsigned short mul_sec_setting_valid;

	//	60-61	Total number of user addresssable logical sectors for 28bit CMD
	unsigned short addressable_logical_sectors_for_28[2];

	//	62	Obsolete
	unsigned short obsolete6;

	//	63	15:11	Reserved
	//		10:8=1 	Multiword DMA mode 210 is selected
	//		7:3 	Reserved
	//		2:0=1 	Multiword DMA mode 210 and below are supported
	unsigned short multWord_DMA_select;

	//	64	15:8	Reserved
	//		7:0	PIO mdoes supported
	unsigned short PIO_mode_supported;

	//	65	Minimum Multiword DMA transfer cycle time per word
	unsigned short min_mulword_DMA_cycle_time_per_word;

	//	66	Manufacturer`s recommended Multiword DMA transfer cycle time
	unsigned short manufacture_recommend_mulword_DMA_cycle_time;

	//	67	Minimum PIO transfer cycle time without flow control
	unsigned short min_PIO_cycle_time_flow_control;

	//	68	Minimum PIO transfer cycle time with IORDY flow control
	unsigned short min_PIO_cycle_time_IOREDY_flow_control;

	//	69-70	Reserved
	unsigned short reserved1[2];

	//	71-74	Reserved for the IDENTIFY PACKET DEVICE command
	unsigned short reserved2[4];

	//	75	Queue depth
	unsigned short queue_depth;

	//	76	Serial ATA Capabilities 
	unsigned short SATA_capabilities;

	//	77	Reserved for Serial ATA 
	unsigned short reserved3;

	//	78	Serial ATA features Supported 
	unsigned short SATA_features_supported;

	//	79	Serial ATA features enabled
	unsigned short SATA_features_enabled;

	//	80	Major Version number
	unsigned short Major_Version;

	//	81	Minor version number
	unsigned short Minor_Version;

	//	82	Commands and feature sets supported
	unsigned short Cmd_feature_sets_supported0;

	//	83	Commands and feature sets supported	
	unsigned short Cmd_feature_sets_supported1;

	//	84	Commands and feature sets supported
	unsigned short Cmd_feature_sets_supported2;

	//	85	Commands and feature sets supported or enabled
	unsigned short Cmd_feature_sets_supported3;

	//	86	Commands and feature sets supported or enabled
	unsigned short Cmd_feature_sets_supported4;

	//	87	Commands and feature sets supported or enabled
	unsigned short Cmd_feature_sets_supported5;

	//	88	15 	Reserved 
	//		14:8=1 	Ultra DMA mode 6543210 is selected 
	//		7 	Reserved 
	//		6:0=1 	Ultra DMA mode 6543210 and below are suported
	unsigned short Ultra_DMA_modes;

	//	89	Time required for Normal Erase mode SECURITY ERASE UNIT command
	unsigned short Time_required_Erase_CMD;

	//	90	Time required for an Enhanced Erase mode SECURITY ERASE UNIT command
	unsigned short Time_required_Enhanced_CMD;

	//	91	Current APM level value
	unsigned short Current_APM_level_Value;

	//	92	Master Password Identifier
	unsigned short Master_Password_Identifier;

	//	93	Hardware resset result.The contents of bits (12:0) of this word shall change only during the execution of a hardware reset.
	unsigned short HardWare_Reset_Result;

	//	94	Current AAM value 
	//		15:8 	Vendor’s recommended AAM value 
	//		7:0 	Current AAM value
	unsigned short Current_AAM_value;

	//	95	Stream Minimum Request Size
	unsigned short Stream_Min_Request_Size;

	//	96	Streaming Transger Time-DMA 
	unsigned short Streaming_Transger_time_DMA;

	//	97	Streaming Access Latency-DMA and PIO
	unsigned short Streaming_Access_Latency_DMA_PIO;

	//	98-99	Streaming Performance Granularity (DWord)
	unsigned short Streaming_Performance_Granularity[2];

	//	100-103	Total Number of User Addressable Logical Sectors for 48-bit commands (QWord)
	unsigned short Total_user_LBA_for_48_Address_Feature_set[4];

	//	104	Streaming Transger Time-PIO
	unsigned short Streaming_Transfer_Time_PIO;

	//	105	Reserved
	unsigned short Reserved4;

	//	106	Physical Sector size/Logical Sector Size
	unsigned short Physical_Logical_Sector_Size;

	//	107	Inter-seek delay for ISO-7779 acoustic testing in microseconds
	unsigned short Inter_seek_delay;

	//	108-111	World wide name	
	unsigned short World_wide_name[4];

	//	112-115	Reserved
	unsigned short Reserved5[4];

	//	116	Reserved for TLC
	unsigned short Reserved6;

	//	117-118	Logical sector size (DWord)
	unsigned short Words_per_Logical_Sector[2];

	//	119	Commands and feature sets supported (Continued from words 84:82)
	unsigned short CMD_feature_Supported;

	//	120	Commands and feature sets supported or enabled (Continued from words 87:85)
	unsigned short CMD_feature_Supported_enabled;

	//	121-126	Reserved for expanded supported and enabled settings
	unsigned short Reserved7[6];

	//	127	Obsolete
	unsigned short Obsolete7;

	//	128	Security status
	unsigned short Security_Status;

	//	129-159	Vendor specific
	unsigned short Vendor_Specific[31];

	//	160	CFA power mode
	unsigned short CFA_Power_mode;

	//	161-167	Reserved for the CompactFlash Association
	unsigned short Reserved8[7];

	//	168	Device Nominal Form Factor
	unsigned short Dev_from_Factor;

	//	169-175	Reserved
	unsigned short Reserved9[7];

	//	176-205	Current media serial number (ATA string)
	unsigned short Current_Media_Serial_Number[30];

	//	206	SCT Command Transport
	unsigned short SCT_Cmd_Transport;

	//	207-208	Reserved for CE-ATA
	unsigned short Reserved10[2];

	//	209	Alignment of logical blocks within a physical block
	unsigned short Alignment_Logical_blocks_within_a_physical_block;

	//	210-211	Write-Read-Verify Sector Count Mode 3 (DWord)
	unsigned short Write_Read_Verify_Sector_Count_Mode_3[2];

	//	212-213	Write-Read-Verify Sector Count Mode 2 (DWord)
	unsigned short Write_Read_Verify_Sector_Count_Mode_2[2];

	//	214	NV Cache Capabilities
	unsigned short NV_Cache_Capabilities;

	//	215-216	NV Cache Size in Logical Blocks (DWord)
	unsigned short NV_Cache_Size[2];

	//	217	Nominal media rotation rate
	unsigned short Nominal_media_rotation_rate;

	//	218	Reserved
	unsigned short Reserved11;

	//	219	NV Cache Options
	unsigned short NV_Cache_Options;

	//	220	Write-Read-Verify feature set current mode
	unsigned short Write_Read_Verify_feature_set_current_mode;

	//	221	Reserved
	unsigned short Reserved12;

	//	222	Transport major version number. 
	//		0000h or ffffh = device does not report version
	unsigned short Transport_Major_Version_Number;

	//	223	Transport Minor version number
	unsigned short Transport_Minor_Version_Number;

	//	224-233	Reserved for CE-ATA
	unsigned short Reserved13[10];

	//	234	Minimum number of 512-byte data blocks per DOWNLOAD MICROCODE command for mode 03h
	unsigned short Mini_blocks_per_CMD;

	//	235	Maximum number of 512-byte data blocks per DOWNLOAD MICROCODE command for mode 03h
	unsigned short Max_blocks_per_CMD;

	//	236-254	Reserved
	unsigned short Reserved14[19];

	//	255	Integrity word
	//		15:8	Checksum
	//		7:0	Checksum Validity Indicator
	unsigned short Integrity_word;
} st_disk_identity_info;

void disk_init();

#endif